iT邦幫忙

2024 iThome 鐵人賽

DAY 22
0

今天我想展示一下我實作的api並利用前幾篇的內容分享給大家更完整的內容。
首先在檔案這裡我先區分了ui跟專屬api的檔案夾
image
輸出其實就只有一個畫面
image
我使用到了一些spinner跟buttun輸入鍵以及顯示的文字
MainActivity

 private TextView result;
    private Button search;
    private Spinner location_spinner,element_spinner,time_spinner;
    private String selected_location,selected_element,selected_time;
    private String[] location_data,element_data,time_data,tw_element;

以及api的變數

 private ApiClient apiClient;
private GetApi getApi;

在oncreate時,先綁定

result = findViewById(R.id.result);
        search = findViewById(R.id.search);
        location_spinner = findViewById(R.id.locationName);
        element_spinner = findViewById(R.id.elementName);
        time_spinner = findViewById(R.id.time);

在res/values/string存這筆資料

<string-array name="location_data">
<item>宜蘭縣</item>
<item>花蓮縣</item>
<item>臺東縣</item>
<item>澎湖縣</item>
<item>金門縣</item>
<item>連江縣</item>
<item>台北市</item>
<item>新北市</item>
<item>桃園市</item>
<item>臺中市</item>
<item>臺南市</item>
<item>高雄市</item>
<item>基隆市</item>
<item>新竹縣</item>
<item>新竹市</item>
<item>苗栗縣</item>
<item>彰化縣</item>
<item>南投縣</item>
<item>雲林縣</item>
<item>嘉義縣</item>
<item>嘉義市</item>
<item>屏東縣</item>
</string-array>

<string-array name="element_data">
<item>Wx</item>
<item>PoP</item>
<item>MinT</item>
<item>CI</item>
<item>MaxT</item>
<item>All</item>
</string-array>

<string-array name="time_data">
<item>今天</item>
<item>明天</item>
<item>後天</item>
</string-array>

<string-array name="tw_element">
<item>當日天氣氣象:</item>
<item>當日降雨機率:</item>
<item>當日最低溫度:</item>
<item>當日舒適度:</item>
<item>當日最高溫度:</item>
</string-array>

在MainActivity
利用這些程式抓取上面需要的選項顯示

 location_data = getResources().getStringArray(R.array.location_data);
        element_data = getResources().getStringArray(R.array.element_data);
        time_data = getResources().getStringArray(R.array.time_data);
        tw_element = getResources().getStringArray(R.array.tw_element);

apiClient = new ApiClient();這裡我把retrofit放在ApiClient這裡,這段程式就是把retrofit設定在MainActivity的變數內。

我的程式裡寫了
getApi = apiClient.myWeatherApi().create(GetApi.class);
但其實可以理解成在apiClient裡的retrofit通過url建立GetApi指定需要抓取的幾筆資料的一個介面存入getApi變數內

接著設定spinner選項列表內被選擇時的功能,這裡spinner+adapter我就跳過了

setSpinner();
        search.setOnClickListener(view -> getWeather(selected_location,selected_element,selected_time));

    }

    private void setSpinner() {
        ArrayAdapter location_adapter = new ArrayAdapter(this, android.R.layout.simple_spinner_dropdown_item, location_data);
        ArrayAdapter element_adapter = new ArrayAdapter(this, android.R.layout.simple_spinner_dropdown_item, element_data);
        ArrayAdapter time_adapter = new ArrayAdapter(this, android.R.layout.simple_spinner_dropdown_item, time_data);

        location_spinner.setAdapter(location_adapter);
        location_spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener(){
            @Override
            public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
                selected_location = location_spinner.getSelectedItem().toString();
            }
            @Override
            public void onNothingSelected(AdapterView<?> adapterView){}
        });

        element_spinner.setAdapter(element_adapter);
        element_spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
                selected_element = element_spinner.getSelectedItem().toString();
            }
            @Override
            public void onNothingSelected(AdapterView<?> adapterView) {}
        });

        time_spinner.setAdapter(time_adapter);
        time_spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
                selected_time = time_spinner.getSelectedItem().toString();
            }
            @Override
            public void onNothingSelected(AdapterView<?> adapterView) {}
        });

最後設定retrofit,這裡我做了一點巧思 ,選擇all時,但其實spinner理會認為這是一個選項並不會全選,所以我把all設成Null,當判斷遇到空值時,做遍歷全部選項當做輸出。

private void getWeather(String selectedLocation, String selectedElement, String selectedTime) {
        String authorization = "CWA-745454D2-A8B2-41D1-A46D-DB35C98E07F0";
        if (selectedElement.equals("All"))
            selectedElement = "";
        String finalSelectedElement = selectedElement;

        getApi.getWeatherApi(authorization,selectedLocation,selectedElement)
                .observeOn(Schedulers.io())
                .subscribeOn(AndroidSchedulers.mainThread())
                .subscribe(new DisposableObserver<WeatherResponse>() {
                    @Override
                    public void onNext( WeatherResponse weatherResponse) {
                        result.setText("");
                        List time_list = Arrays.asList(time_data);
                        List element_list = Arrays.asList(element_data);
                        if(weatherResponse.getElementSize() != 1){
                            for (int i = 0; i < weatherResponse.getElementSize(); i++) {
                                result.append(tw_element[i] + weatherResponse.getDataByTime(i,time_list.indexOf(selectedTime))+"\n");
                            }
                        }
                        else {
                            result.setText(tw_element[element_list.indexOf(finalSelectedElement)] + weatherResponse.getDataByTime(0,time_list.indexOf(selectedTime))+"\n");
                        }
                    }

                    @Override
                    public void onError( Throwable e) {
                        Log.d("test", "onError: ");
                    }

                    @Override
                    public void onComplete() {
                        Log.d("test", "onComplete: ");
                    }
                });
    }

ApiClient的程式

public class ApiClient {
    public Retrofit myWeatherApi(){
        return new Retrofit.Builder()
                .baseUrl("https://opendata.cwa.gov.tw/api/v1/rest/datastore/")
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(retrofit2.adapter.rxjava3.RxJava3CallAdapterFactory.create())
                .build();
    }
}

WeatherResponse

public class WeatherResponse {
    public Records records;

    public class Records{
        public List<Location> location;

    }
    public class Location{
        public String locationName;
        public List<WeatherElement> weatherElement;
    }

    public class WeatherElement {
        public String elementName;
        public List<Time> time;
    }
    public class Time {
        public Parameter parameter;
    }

    public class Parameter{
        public String parameterName;
        public String parameterUnit;
    }



    public String getDataByTime(Integer index,Integer day){
        return records.location.get(0).weatherElement.get(index).time.get(day).parameter.parameterName;
    }
    public Integer getElementSize(){
        return records.location.get(0).weatherElement.size();
    }

}

GetApi

public interface GetApi {
    @GET("F-C0032-001")
    Observable<WeatherResponse> getWeatherApi(
            @Query("Authorization") String Authorization,
            @Query("locationName") String locationName,
            @Query("elementName") String elementName
    );
}

依賴性

app/Gradle Scripts/build gradle(app)

dependencies {
    implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
    implementation 'com.squareup.retrofit2:retrofit:2.9.0'
    //Retrofit

    implementation 'com.squareup.retrofit2:adapter-rxjava3:2.9.0'
    implementation 'io.reactivex.rxjava3:rxjava:3.1.6'
    implementation 'io.reactivex.rxjava3:rxandroid:3.0.0'
    //RxJava
}

成果展示時間


上一篇
[day21]API-實用的Retrofit+Rxjava
下一篇
[day23]測試api
系列文
深入Android 物件的認識與應用實踐30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言